package com.dualsportmaps.android.views;

import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import net.osmand.plus.OsmandSettings;
import net.osmand.plus.OsmandSettings.MetricsConstants;
import net.osmand.plus.views.OsmandMapLayer;
import net.osmand.plus.views.OsmandMapTileView;

import org.apache.commons.logging.Log;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Cap;
import android.graphics.Paint.Join;
import android.graphics.Paint.Style;
import android.graphics.Path;
import android.graphics.PointF;
import android.graphics.RectF;
import android.graphics.drawable.BitmapDrawable;
import android.util.DisplayMetrics;
import android.view.View;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.Toast;

import com.dualsportmaps.android.DsmConnectionFactory;
import com.dualsportmaps.android.DsmMapDownload;
import com.dualsportmaps.android.DsmResourceManager;
import com.dualsportmaps.android.DsmResourceManager.DsmResourceManagerException;
import com.dualsportmaps.android.EncodedPolyline;
import com.dualsportmaps.android.IDsmMapDownloadListener;
import com.dualsportmaps.android.LogUtil;
import com.dualsportmaps.android.SimpleTrackpoint;
import com.dualsportmaps.android.activities.SearchDSMActivity;
import com.dualsportmaps.android.model.DsmMapPhoto;
import com.dualsportmaps.android.model.DsmMapTrack;
import com.dualsportmaps.android.model.DsmMapWpt;
import com.dualsportmaps.android.shared.model.DsmMapProxy;
import com.google.web.bindery.requestfactory.shared.Receiver;
import com.google.web.bindery.requestfactory.shared.ServerFailure;

public class DsmMapLayer implements OsmandMapLayer, IDsmMapDownloadListener {

	private OsmandMapTileView view;
	private Path path;
	public RectF latLonBounds = new RectF();
	private final static Log log = LogUtil.getLog(DsmMapLayer.class);
	private List<DsmMapWpt> visibleWaypoints = new ArrayList<DsmMapWpt>();
	private List<DsmMapPhoto> visiblePhotos = new ArrayList<DsmMapPhoto>();
	private HashMap<String,Bitmap> scaledIcons;
	private DisplayMetrics dm;
	private List<VisibleTrackData> visibleTrackData = new ArrayList<VisibleTrackData>();
	private EncodedPolyline selectedEncodedPolyline = null;
	public DsmMapLayer() {
	}

	private void initUI() {
		path = new Path();
		dm = new DisplayMetrics();
		WindowManager wmgr = (WindowManager) view.getContext().getSystemService(Context.WINDOW_SERVICE);
		wmgr.getDefaultDisplay().getMetrics(dm);
	}


	@Override
	public void initLayer(OsmandMapTileView view) {
		this.view = view;
		initUI();
	}
 
	@Override
	public void onDraw(Canvas canvas, RectF latLonBounds, boolean nightMode) {
		try {
			this.latLonBounds = new RectF(latLonBounds);
			visibleWaypoints = new ArrayList<DsmMapWpt>(); 
			visiblePhotos = new ArrayList<DsmMapPhoto>();
			if(!isVisible())
				return;
			scaledIcons = new HashMap<String,Bitmap>();
			visibleTrackData.clear();
			for (final DsmMapDownload map : DsmResourceManager.getDsmResourceManager().getActiveDsmMaps()) {
				if(trackOnScreen(new RectF(map.getMap().getDsmMapBound1Lng().floatValue(),map.getMap().getDsmMapBound1Lat().floatValue(),map.getMap().getDsmMapBound2Lng().floatValue(),map.getMap().getDsmMapBound2Lat().floatValue()),latLonBounds)) {
					canvas.save();
					if(view.showPerspective()) 
						view.addPerspective(canvas);
					if(view.getRotate() != 0)
						canvas.rotate(view.getRotate(), view.getCenterPointX(), view.getCenterPointY());
					boolean selectedLoaded = false;
					for (EncodedPolyline ep : map.getEncodedPolylines()) {
						if(ep.equals(selectedEncodedPolyline)) {
							selectedLoaded = true;
						}
						if(trackOnScreen(new RectF(ep.bound1Lng,ep.bound1Lat,ep.bound2Lng,ep.bound2Lat),latLonBounds)) {
							if(ep.hasTrackPointsInRect(view.getZoom(),latLonBounds)) {
								List<SimpleTrackpoint> l = ep.getTrackPoints(view.getZoom());
								visibleTrackData.add(new VisibleTrackData(ep,map,l));
								Paint paint;
								if(ep.equals(selectedEncodedPolyline)) {
									paint = getActiveTrackPaint();
								} else {
									paint = getTrackPaint(ep.getColor());
								}
								path.rewind();
								int startIndex = -1;							
								for (int i = 0; i < l.size(); i++) {
									SimpleTrackpoint ls = l.get(i);
									if (startIndex == -1) {
										if (ls.getLatitude() >= latLonBounds.bottom && ls.getLatitude() <= latLonBounds.top  && ls.getLongitude() >= latLonBounds.left 
												&& ls.getLongitude() <= latLonBounds.right ) {
											startIndex = i > 0 ? i - 1 : i;
										}
									} else if (!(latLonBounds.left <= ls.getLongitude() + 0.03 && ls.getLongitude() - 0.03 <= latLonBounds.right
											&& latLonBounds.bottom <= ls.getLatitude() + 0.03 && ls.getLatitude() - 0.03 <= latLonBounds.top)) {
										drawSegment(canvas, l, startIndex, i, paint);
										startIndex = -1;
									}
								}
								if (startIndex != -1) {
									drawSegment(canvas, l, startIndex, l.size() - 1, paint);
									continue;
								}
							}
						}
					}
					if(!selectedLoaded)
						selectedEncodedPolyline = null;
					canvas.restore();
					if(view.getZoom() >= 10) {
						int shrinkageSize = 24 + (view.getZoom()-10)*2;		
						if(selectedEncodedPolyline != null) {
							for (int i = 0; i < selectedEncodedPolyline.markerPoints.size(); i++) {
								SimpleTrackpoint ls = selectedEncodedPolyline.markerPoints.get(i);
								if(trackOnScreen(new RectF(ls.getLongitude(),ls.getLatitude(),ls.getLongitude(),ls.getLatitude()),latLonBounds)) {
									double dist = selectedEncodedPolyline.distancePoints.get(i)/1000;
									String unit = " kms.";
									if(OsmandSettings.getDefaultMetricConstants(DsmResourceManager.getApplicationContext()) != MetricsConstants.KILOMETERS_AND_METERS) {
										dist *= 0.621371f;
										unit = " miles.";
									}
									dist = (double)((int)(dist*10))/10;
									DsmMapWpt wpt = new DsmMapWpt("","","Distance Marker",dist + unit,(double)ls.getLatitude(),(double)ls.getLongitude(),"Mile Marker");
									visibleWaypoints.add(wpt);
									int[] ps = view.getRotatedMapPoints(wpt.getDsmMapWptLat(),wpt.getDsmMapWptLng());
									int x = ps[0]-shrinkageSize/2;
									int y = ps[1]-shrinkageSize/2;
									
									try {
										canvas.drawBitmap(getScaledIcon(wpt.getDsmMapWptIcon(),shrinkageSize),x,y,null);
									} catch (Exception e) {
										e.printStackTrace();
									}
								}
							}
						}
						for (DsmMapWpt wpt : map.getWaypoints()) {
							if(trackOnScreen(new RectF(wpt.getDsmMapWptLng().floatValue(),wpt.getDsmMapWptLat().floatValue(),wpt.getDsmMapWptLng().floatValue(),wpt.getDsmMapWptLat().floatValue()),latLonBounds)) {
								visibleWaypoints.add(wpt);
								int[] ps = view.getRotatedMapPoints(wpt.getDsmMapWptLat(),wpt.getDsmMapWptLng());
								int x = ps[0]-shrinkageSize/2;
								int y = ps[1]-shrinkageSize/2;
								
								try {
									canvas.drawBitmap(getScaledIcon(wpt.getDsmMapWptIcon(),shrinkageSize),x,y,null);
								} catch (Exception e) {
									e.printStackTrace();
								}
							}
						}
						if(OsmandSettings.isInternetConnectionAvailable(DsmResourceManager.getApplicationContext())) {
							for (DsmMapPhoto photo : map.getPhotos()) {
								if(trackOnScreen(new RectF(photo.getDsmMapPhotoLng().floatValue(),photo.getDsmMapPhotoLat().floatValue(),photo.getDsmMapPhotoLng().floatValue(),photo.getDsmMapPhotoLat().floatValue()),latLonBounds)) {
									visiblePhotos.add(photo);
									int[] ps = view.getRotatedMapPoints(photo.getDsmMapPhotoLat(),photo.getDsmMapPhotoLng());
									int x = ps[0]-shrinkageSize/2;
									int y = ps[1]-shrinkageSize/2;
									
									try {
										canvas.drawBitmap(getScaledIcon("Photo",shrinkageSize),x,y,null);
									} catch (Exception e) {
										e.printStackTrace();
									}
								}
							}
						}
					}
				} else {
					if(DsmResourceManager.getDsmResourceManager(view.getApplication()).dontprintMap())
						new Thread(new Runnable(){
							@Override
							public void run() {
								map.clearEncodedPolylines();
							}}).start();						
				}
			}
		} 
		catch (DsmResourceManagerException e) {
			log.debug(e.getMessage());
		}
		catch (Throwable e) {
			log.debug(e.getMessage());
//			com.dualsportmaps.android.LogUtil.getLog(cl)
		}
	}
	
	private Bitmap getScaledIcon(String icon, int size) throws Throwable {
		Bitmap retval = scaledIcons.get(icon+"_"+size);
		if(retval == null) {
			retval = DsmResourceManager.getScaledIcon(icon,size);
			scaledIcons.put(icon+"_"+size, retval);
		}
		return retval;
		
	}
	
	private void drawSegment(Canvas canvas, List<SimpleTrackpoint> l, int startIndex, int endIndex, Paint paint) {
		double startLng = l.get(startIndex).getLongitude();
		double startLat = l.get(startIndex).getLatitude();
		int px = view.getMapXForPoint(startLng);
		int py = view.getMapYForPoint(startLat);
		path.moveTo(px,py);
		for (int i = startIndex + 1; i <= endIndex; i++) {
			SimpleTrackpoint p = l.get(i);
			int x = view.getMapXForPoint(p.getLongitude());
			int y = view.getMapYForPoint(p.getLatitude());
			path.lineTo(x,y);
		}
		canvas.drawPath(path, paint);
	}
	
	public boolean trackOnScreen(RectF trackbox, RectF latLonBounds) {
		RectF parentBox = new RectF(latLonBounds);
		trackbox.sort();
		parentBox.sort();
		if(RectF.intersects(parentBox, trackbox)) {
			return true;
		}
		if(new RectF(latLonBounds).contains(new RectF(trackbox))) {
			return true;
		}
		if(new RectF(trackbox).contains(new RectF(latLonBounds))) {
			return true;		
		}
		return false;
	}
	public boolean isVisible() {
		try {
			return !DsmResourceManager.getDsmResourceManager().mapActive.isEmpty();
		} catch (DsmResourceManagerException e) {
			return false;
		}
	}
	
	@Override
	public void destroyLayer() {
		view = null;
	}

	public DsmMapWpt getWaypointFromPoint(PointF point){
		DsmMapWpt result = null;
		if (visibleWaypoints.size() > 0) {
			int ex = (int) point.x;
			int ey = (int) point.y;
			int radius = getRadiusPoi(view.getZoom()) * 3 / 2;
			try {
				for (DsmMapWpt n : visibleWaypoints) {
					int x = view.getRotatedMapXForPoint(n.getDsmMapWptLat(), n.getDsmMapWptLng());
					int y = view.getRotatedMapYForPoint(n.getDsmMapWptLat(), n.getDsmMapWptLng());
					if (Math.abs(x - ex) <= radius && Math.abs(y - ey) <= radius) {
//						radius = Math.max(Math.abs(x - ex), Math.abs(y - ey));
						return n;
					}
				}
			} catch (IndexOutOfBoundsException e) {
				// that's really rare case, but is much efficient than introduce synchronized block
			}
		}
		return result;
	}
	public DsmMapPhoto getPhotoFromPoint(PointF point){
		DsmMapPhoto result = null;
		if (visiblePhotos.size() > 0) {
			int ex = (int) point.x;
			int ey = (int) point.y;
			int radius = getRadiusPoi(view.getZoom()) * 3 / 2;
			try {
				for (DsmMapPhoto n : visiblePhotos) {
					int x = view.getRotatedMapXForPoint(n.getDsmMapPhotoLat(), n.getDsmMapPhotoLng());
					int y = view.getRotatedMapYForPoint(n.getDsmMapPhotoLat(), n.getDsmMapPhotoLng());
					if (Math.abs(x - ex) <= radius && Math.abs(y - ey) <= radius) {
//						radius = Math.max(Math.abs(x - ex), Math.abs(y - ey));
						return n;
					}
				}
			} catch (IndexOutOfBoundsException e) {
				// that's really rare case, but is much efficient than introduce synchronized block
			}
		}
		return result;
	}
	public VisibleTrackData getTrackFromPoint(PointF point){
		VisibleTrackData result = null;
		if (visibleTrackData.size() > 0) {
			int ex = (int) point.x;
			int ey = (int) point.y;
			int radius = getRadiusPoi(view.getZoom()) * 3 / 2;
			try {
				for(VisibleTrackData vtd : visibleTrackData) {
					for (SimpleTrackpoint n : vtd.tps) {
						int x = view.getRotatedMapXForPoint(n.getLatitude(), n.getLongitude());
						int y = view.getRotatedMapYForPoint(n.getLatitude(), n.getLongitude());
						if (Math.abs(x - ex) <= radius && Math.abs(y - ey) <= radius) {
//							radius = Math.max(Math.abs(x - ex), Math.abs(y - ey));
							return vtd;							
						}
					}
				}
			} catch (IndexOutOfBoundsException e) {
				// that's really rare case, but is much efficient than introduce synchronized block
			}
		}
		return result;
	}
	private int getRadiusPoi(int zoom){
		int r = 0;
		if(zoom < 10){
			r = 0;
		} else if(zoom <= 15){
			r = 10;
		} else if(zoom == 16){
			r = 14;
		} else if(zoom == 17){
			r = 16;
		} else {
			r = 18;
		}
		return (int) (r * dm.density);
	}	

	@Override
	public boolean onTouchEvent(PointF point) {
		if(OsmandSettings.isInternetConnectionAvailable(DsmResourceManager.getApplicationContext())) {
			final DsmMapPhoto p = getPhotoFromPoint(point);
			if(p != null){
				new Thread(new Runnable(){
					@Override
					public void run() {
						try {
							URL url = new URL(p.getMedium());
							final ImageView imageview = new ImageView(view.getContext());
							imageview.setImageBitmap(BitmapFactory.decodeStream((InputStream)url.getContent()));
							DsmResourceManager.getMapActivity().runOnUiThread(new Runnable() {

								@Override
								public void run() {
									String format = p.getDsmMapPhotoCaption();
									Toast toast = Toast.makeText(view.getContext(), format, Toast.LENGTH_LONG);									
									View textView = toast.getView();
									LinearLayout lay = new LinearLayout(view.getContext());
									lay.setOrientation(LinearLayout.VERTICAL);
									lay.addView(imageview);
									if(p.getDsmMapPhotoCaption().length() > 0) {
										lay.addView(textView);
									}
									toast.setView(lay);
									toast.show();
								}});
						} catch (Exception e) {
							e.printStackTrace();
							DsmResourceManager.getMapActivity().runOnUiThread(new Runnable() {
								@Override
								public void run() {
									Toast.makeText(view.getContext(), "Photo Unavailable", Toast.LENGTH_SHORT).show();
								}
							});								
						}
					}}).start();;
				return true;
			}
		}
		final DsmMapWpt n = getWaypointFromPoint(point);
		if(n != null){
			try {
				AlertDialog.Builder dialog = new AlertDialog.Builder(view.getContext());
				dialog.setIcon(new BitmapDrawable(DsmResourceManager.getScaledIcon(n.getDsmMapWptIcon(),40)));
				
				dialog.setTitle("Waypoint");
				String wptinfo = n.getDsmMapWptName();
				if(n.getDsmMapWptDesc() != null)
					if(!n.getDsmMapWptDesc().equals(wptinfo))
						wptinfo = wptinfo + "\n" + n.getDsmMapWptDesc();
				dialog.setMessage(wptinfo);
				dialog.setNeutralButton("Options", new DialogInterface.OnClickListener(){

					@Override
					public void onClick(DialogInterface dialog, int which) {
						DsmResourceManager.getMapActivity().contextMenuPoint(n.getDsmMapWptLat(), n.getDsmMapWptLng());
					}});
				final AlertDialog d = dialog.create();
				d.show();
				new Thread(new Runnable() {

					@Override
					public void run() {
						try {
							Thread.sleep(3000);
							d.dismiss();
						} catch (InterruptedException e) {
						}
					}}).start();			
				return true;
			} catch (Throwable e) {
				e.printStackTrace();
			}
		}
		final VisibleTrackData track = getTrackFromPoint(point);
		if(track != null) {
			if(track.ep.equals(selectedEncodedPolyline)) {
				selectedEncodedPolyline = null;
				view.refreshMap();
			} else {
				selectedEncodedPolyline = track.ep;
				if(track.dsmMapTrack.getDsmMapTrackName() != null) {
					float dist = track.dsmMapTrack.getDsmMapTrackDistance();
					String unit = " kms.";
					if(OsmandSettings.getDefaultMetricConstants(DsmResourceManager.getApplicationContext()) != MetricsConstants.KILOMETERS_AND_METERS) {
						dist *= 0.621371f;
						unit = " miles.";
					}
					dist = (float)((int)(dist*10))/10;
					String diff = "";
					if(track.dsmMapTrack.getDsmMapTrackDifficulty() != null) {
						int id = track.dsmMapTrack.getDsmMapTrackDifficulty();
						if(id == 1) {
							diff = "\nHighway";
						} else if(id == 2) {
							diff = "\nEasy";
						} else if(id == 3) {
							diff = "\nModerate";
						} else if(id == 4) {
							diff = "\nDifficult";
						} else if(id == 5) {
							diff = "\nExtreme";
						} else if(id == 6) {
							diff = "\nHiking";
						}  
					}
					showToast(track.dsmMapTrack.getDsmMapTrackName() + "\nDistance: " + dist + unit + diff);
					view.refreshMap();
				}
			}
			return true;
		}
		return false; 
	}

	@Override
	public boolean onLongPressEvent(PointF point) {
		return false;
	}

	@Override
	public boolean drawInScreenPixels() {
		return true;
	}
	
	private Paint getTrackPaint(String color) {
		int width = 3;
		int c = Color.parseColor(color);
		if(view.getZoom() > 16)
			width = 12;
		else if(view.getZoom() > 14)
			width = 8;
		else if(view.getZoom() > 11)
			width = 6;
		else if(view.getZoom() > 8)
			width = 4;
		else
			width = 2;
		Paint paint = new Paint();
		paint.setColor(c);	
		paint.setAlpha(180);
		paint.setStyle(Style.STROKE);
		paint.setStrokeWidth(width);
		paint.setStrokeCap(Cap.ROUND);
		paint.setStrokeJoin(Join.ROUND);
		return paint;
	}
	
	private Paint getActiveTrackPaint() {
		int width = 4;
		int c = Color.MAGENTA;
		if(view.getZoom() > 16)
			width = 13;
		else if(view.getZoom() > 14)
			width = 9;
		else if(view.getZoom() > 11)
			width = 7;
		else if(view.getZoom() > 8)
			width = 5;
		else
			width = 3;
		Paint paint = new Paint();
		paint.setColor(c);	
		paint.setAlpha(200);
		paint.setStyle(Style.STROKE);
		paint.setStrokeWidth(width);
		paint.setStrokeCap(Cap.ROUND);
		paint.setStrokeJoin(Join.ROUND);
		return paint;
	}
	
	public boolean showAllMaps = true;
	@Override
	public void addDsmMap(DsmMapDownload dsmMapDownload) {
		downloadcount--;
		boolean searchResults = dsmMapDownload.getMap().getDsmMapId().equals("SEARCHRESULTS");
		if(searchResults) {
			showAllMaps = false;
			DsmResourceManager.getDsmResourceManager(DsmResourceManager.getApplication()).hideAllMaps();
		}			
		if(showAllMaps || searchResults) {
			if(searchResults || !DsmResourceManager.getDsmResourceManager(DsmResourceManager.getApplication()).dontprintMap()) {
				DsmResourceManager.getDsmResourceManager(DsmResourceManager.getApplication()).showDsmMap(dsmMapDownload);	
			}
		}		
		if(downloadcount == 0) {
			DsmMapDownload.removeListener(this);
			SearchDSMActivity.title = "Search Results";
//			showToast("Map downloads complete.");
			if(showAllMaps)
				DsmMapDownload.removeDsmMapDownload("SEARCHRESULTS");
			else
				showAllMaps = true;
		}
	}

	@Override
	public void removeDsmMap(String dsmMapId) {
	}
	private int downloadcount = 0;
	public void searchDsmMapView() {
		DsmMapDownload.removeDsmMapDownload("SEARCHRESULTS");
		downloadcount = 0;
		List<DsmMapDownload> savedMaps = DsmResourceManager.getDsmResourceManager(DsmResourceManager.getApplication()).getDsmMaps();
		final ArrayList<String> possibleMaps = new ArrayList<String>();
		int sideLoadedCount = 0;
		for(DsmMapDownload map : savedMaps) {
			if(map.getMap().getDsmMapId().startsWith("GPX"))
				sideLoadedCount++;
			if(this.trackOnScreen(new RectF(map.getMap().getDsmMapBound1Lng().floatValue(),map.getMap().getDsmMapBound1Lat().floatValue(),map.getMap().getDsmMapBound2Lng().floatValue(),map.getMap().getDsmMapBound2Lat().floatValue()),view.getLatlonRect())) {
				for (EncodedPolyline ep : map.getEncodedPolylines()) {
					if(ep.hasTrackPointsInRect(view.getZoom(),view.getLatlonRect())) {
						possibleMaps.add(map.getMap().getDsmMapId());
						if(!DsmResourceManager.getDsmResourceManager(DsmResourceManager.getApplication()).dontprintMap())
							DsmResourceManager.getDsmResourceManager(DsmResourceManager.getApplication()).showDsmMap(map);
						break;
					}
				}
				if(!possibleMaps.contains(map.getMap().getDsmMapId())) {
					DsmResourceManager.getDsmResourceManager(DsmResourceManager.getApplication()).hideMap(map);
				}
			} else {
				DsmResourceManager.getDsmResourceManager(DsmResourceManager.getApplication()).hideMap(map);
			}
		}		
		Intent newIntent = new Intent(DsmResourceManager.getMapActivity(), SearchDSMActivity.class);
		newIntent.putExtra("showActiveOnly", true);
		newIntent.putStringArrayListExtra("maplist", possibleMaps);		
		DsmResourceManager.getMapActivity().startActivity(newIntent);
		final int pmsminusgps = possibleMaps.size() - sideLoadedCount;
		if(view.getZoom() >= 9) {
			if(OsmandSettings.isUsingInternetToDownloadTiles(OsmandSettings.getPrefs(DsmResourceManager.getApplicationContext())) && OsmandSettings.isInternetConnectionAvailable(DsmResourceManager.getApplicationContext())) {
				new Thread(new Runnable(){
					@Override
					public void run() {
						DsmConnectionFactory.authenticateDsmAppUser();
						DsmConnectionFactory.getDsmConnection().getDsmMapsByLocation(Float.valueOf(DsmMapLayer.this.latLonBounds.left).doubleValue(), Float.valueOf(DsmMapLayer.this.latLonBounds.right).doubleValue(), Float.valueOf(DsmMapLayer.this.latLonBounds.top).doubleValue(), Float.valueOf(DsmMapLayer.this.latLonBounds.bottom).doubleValue()).fire(new Receiver<List<DsmMapProxy>>() {
							
							@Override
							public void onSuccess(List<DsmMapProxy> maps) {
								if(maps.size() - pmsminusgps > 25) {
									showToast("Too many results. Please zoom in and try again.");
								} else { //if(maps.size() - pmsminusgps > 0) {
									downloadcount = maps.size();
									boolean lotsofmaps = downloadcount-pmsminusgps > 3;
									DsmMapDownload.addListener(DsmMapLayer.this);
									int x = 1;
									SearchDSMActivity.title = "Downloading Maps";
									if(lotsofmaps) {
										showToast("New maps available.");									
										x = 0;
									}
									for(int xx = x;xx < maps.size();xx++) {
										DsmMapProxy map = maps.get(xx);
										try {
											new DsmMapDownload(map.getDsmMapId(),true, DsmResourceManager.getMapActivity(),true);
											if(xx == 0)
												Thread.sleep(750); //So 
										} catch (Exception e) {
											downloadcount--;
											showToast("Map download failed.");
										}
									}
									maps = null;
								}
							}

							@Override
							public void onFailure(ServerFailure error) {
								showToast("An error occured. Are you online? If so, the server may be having issues.\n" + error.getMessage());
							}
						});
					}}).start();
			}
		} else {
			showToast("Please zoom in to level 9 or more long click to see the list of stored maps.");
		}
	}
	private void showToast(final String message) {
		try {
			DsmResourceManager.getMapActivity().runOnUiThread(new Runnable() {

				@Override
				public void run() {
					Toast.makeText(DsmResourceManager.getMapActivity(),message,Toast.LENGTH_LONG).show();
				}});
		} catch (Exception e) {
		}
	}
	private class VisibleTrackData {
		DsmMapTrack dsmMapTrack;
		List<SimpleTrackpoint> tps;
		EncodedPolyline ep;
		private VisibleTrackData(EncodedPolyline ep, DsmMapDownload map, List<SimpleTrackpoint> tps) {
			dsmMapTrack = map.getTracks().get(map.getEncodedPolylines().indexOf(ep));
			this.ep = ep;
			this.tps = tps;
		}
	}
}
